home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / FAQSYS18.ZIP / FAQS.DAT / CDROMFAQ.100 / text0000.txt < prev   
Encoding:
Text File  |  1995-12-12  |  24.5 KB  |  704 lines

  1. In recognition of a number of questions I've seen recently asking 
  2. questions on programming CD-ROMs...
  3.  
  4. CD-ROM programming FAQ Version 1.00
  5.  
  6. Copyright (C) 1995 by Marcus W. Johnson. All rights reserved. This
  7. article is not in the public domain, but it may be redistributed so
  8. long as this notice, the acknowledgments, and the information on
  9. obtaining the latest copy of this list are retained and no fee is
  10. charged. The code fragments may be used freely; credit would be
  11. polite.
  12.  
  13. ------- Table of Contents --------------------------------------------
  14.  
  15. Section 0 - Availability
  16.  0.01. How can I get the latest copy of this FAQ?
  17. Section 1 - MSCDEX Status
  18.  1.01. How do I know if MSCDEX is installed?
  19.  1.02. How do I determine the MSCDEX version?
  20. Section 2 - CD-ROM Existence
  21.  2.01. How many CD-ROMs are present?
  22.  2.02. Which drives are CD-ROMs?
  23.  2.03. How do I get the name of the CD-ROM device driver?
  24. Section 3 - Drive Interface
  25.  3.01. How do I open the door?
  26.  3.02. How do I close the door?
  27.  3.03. How do I unlock the door?
  28.  3.04. How do I lock the door?
  29.  3.05. How do I reset the drive?
  30.  3.06. How do I get drive status?
  31. Section 4 - Drive Capacity
  32.  4.01. What sector size is supported?
  33.  4.02. How many sectors are on the disk?
  34.  4.03. How much data is on the disk?
  35. Section 5 - Volume Table of Contents
  36.  5.01. How do I get the abstract file name?
  37.  5.02. How do I get the bibliography file name?
  38.  5.03. How do I get the copyright file name?
  39.  5.04. How do I read the Volume Table of Contents (VTOC)?
  40. Section 6 - Audio
  41.  6.01. How do I find out how many tracks are on a CD?
  42.  6.02. What are Red Book and HSG formats?
  43.  6.03. How can I determine where a particular track starts?
  44.  6.04. How do I play audio?
  45.  6.05. How do I pause audio playback?
  46.  6.06. How do I resume audio playback?
  47.  
  48. ======================================================================
  49. Section 0 - Administration
  50. ----------------------------------------------------------------------
  51. 0.01. How can I get the latest copy of this FAQ?
  52.  
  53.       The FAQ is published monthly in comp.os.msdos.programming and
  54.       alt.msdos.programmer.
  55. ----------------------------------------------------------------------
  56. 0.02. Where did this information come from?
  57.  
  58.       Ralf Brown's interrupt list
  59.       "MS-DOS Extensions", by Ray Duncan, Microsoft Press
  60.       My personal research for "PC-Programmer's Guide to Low-Level
  61.       Functions and Interrupts", Sams
  62.       The mention of particular books or programs must not be construed
  63.       to reflect unfavorably on any that are not mentioned.
  64. ----------------------------------------------------------------------
  65. 0.03. How accurate is this information?
  66.  
  67.       I have personally tested the code fragments in this FAQ, and
  68.       they appear to work as advertised, but there is no warranty on
  69.       the code or on the techniques described in this article.
  70.       As testing may not have been perfect, and machines and
  71.       configurations vary, it is possible that the fragments will not
  72.       work for you.
  73.       Please send corrections to marcj@nando.net.
  74. ======================================================================
  75. Section 1 - MSCDEX Status
  76. ======================================================================
  77. 1.01. How do I know if MSCDEX is installed?
  78.  
  79.       Call the MSCDEX installation check function. Here's code that
  80.       performs the check:
  81.  
  82.       mov  AX,0DADAH
  83.       push AX
  84.       mov  AX,01100H
  85.       int  2FH
  86.       pop  BX
  87.       cmp  BX,0ADADH
  88.       jne  not_installed
  89.       cmp  AL,0FFH
  90.       jne  not_installed
  91.       ;
  92.       ; MSCDEX is installed
  93.       ;
  94. ----------------------------------------------------------------------
  95. 1.02. How do I determine the MSCDEX version?
  96.  
  97.       Call the MSCDEX version check function. Here's code that gets
  98.       the version:
  99.  
  100.       mov  AX,150CH
  101.       int  2FH
  102.       ;
  103.       ; BH holds the major version
  104.       ; BL holds the minor version
  105.       ; Prior to MSCDEX version 2.0, the version returned is 0.0 (BX =
  106.       ; 0)
  107.       ;
  108. ======================================================================
  109. Section 2 - CD-ROM Existence
  110. ======================================================================
  111. 2.01. How many CD-ROMs are present?
  112.  
  113.       Ask MSCDEX. Here's code that gives the count of CD-ROMs
  114.       installed and the drive letter of the first one:
  115.  
  116.       mov  AX,1500H
  117.       xor  BX,BX
  118.       int  2FH
  119.       ;
  120.       ; BX will hold the number of CD-ROMs
  121.       ; CL will hold the first CD-ROM's drive; 0 = A:, 1 = B:, and so
  122.       ; on
  123.       ;
  124.  
  125.       A problem with this method, BTW, is that it conflicts with DOS
  126.       4.0's GRAPHICS.COM.
  127. ----------------------------------------------------------------------
  128. 2.02. Which drives are CD-ROMs?
  129.  
  130.       There are two ways to find out. Both ways require MSCDEX version
  131.       2 (see question 1.02, How do I determine the MSCDEX version?).
  132.       The first way gives a list of all CD-ROM drives; the second
  133.       verifies whether a specific drive is a CD-ROM.
  134.  
  135.       Method 1: (get list of CD-ROMs)
  136.       This method requires a block of memory; the size, in bytes, must
  137.       be at least the number of drives returned by function 1500H (see
  138.       question 2.01, How many CD-ROMs are present?).
  139.  
  140.       mov  AX,150DH
  141.       les  BX,LetterArray
  142.       int    2FH
  143.       ;
  144.       ; each byte in LetterArray will contain a drive value (0 = A:, 1
  145.       ; = B:, etc.)
  146.       ;
  147.  
  148.       Method 2: (is a specified drive a CD-ROM?)
  149.  
  150.       mov  AX,150BH
  151.       mov  CX,Drive  ; 0 = A:, 1 = B:, and so on
  152.       int  2FH
  153.       or   AX,AX
  154.       jz   not_cd_rom
  155.       cmp  BX,0ADADH
  156.       jne  not_cd_rom
  157.       ;
  158.       ; the drive is a CD-ROM
  159.       ;
  160. ----------------------------------------------------------------------
  161. 2.03. How do I get the name of the CD-ROM device driver?
  162.  
  163.       First, you need to know how many CD-ROMs you have (see question
  164.       2.01, How many CD-ROMs are present?). You need a block of memory
  165.       whose size, in bytes, is 5 times the number of CD-ROMs present.
  166.       This code will fill that array:
  167.  
  168.       mov  AX,1501H
  169.       les  BX,DriverArray
  170.       int  2FH
  171.  
  172.       Each 5-byte element in the array consists of the drive's subunit
  173.       number (a CD-ROM device driver may support several drives as
  174.       subunits), followed by the address of the drive's device driver.
  175.       The filename is 10 bytes into the device driver. The filename is
  176.       at most 8 bytes long, and if less than 8 bytes, is terminated by
  177.       a space (20H).
  178. ======================================================================
  179. Section 3 - Drive Interface
  180. ======================================================================
  181. 3.01. How do I open the door?
  182.  
  183.       First, you need the name of the device driver (see question 2.03,
  184.       How do I get the name of the CD-ROM device driver?). Open the
  185.       file for read/write and obtain the file handle (DOS function 3DH
  186.       will suffice).
  187.  
  188.       Once you have the file handle, you need a one byte block of
  189.       memory. Call DOS IOCTL function 4403H, as shown here:
  190.  
  191.       mov  BX,FileHandle
  192.       mov  Command,0
  193.       lds  DX,Command
  194.       mov  CX,1
  195.       mov  AX,4403H
  196.       int  21H
  197.       jc   error
  198.       cmp  AX,1
  199.       jne  write_error
  200.       ;
  201.       ; door should be open
  202.       ;
  203.  
  204.       On error (carry set), AX will hold an error code: 0001H (invalid
  205.       function), 0005H (access denied), 0006H (invalid handle), or
  206.       000DH (invalid data).
  207. ----------------------------------------------------------------------
  208. 3.02. How do I close the door?
  209.  
  210.       First, you need the name of the device driver (see question 2.03,
  211.       How do I get the name of the CD-ROM device driver?). Open the
  212.       file for read/write and obtain the file handle (DOS function 3DH
  213.       will suffice).
  214.  
  215.       Once you have the file handle, you need a one byte block of
  216.       memory. Call DOS IOCTL function 4403H, as shown here:
  217.  
  218.       mov  BX,FileHandle
  219.       mov  Command,5
  220.       lds  DX,Command
  221.       mov  CX,1
  222.       mov  AX,4403H
  223.       int  21H
  224.       jc   error
  225.       cmp  AX,1
  226.       jne  write_error
  227.       ;
  228.       ; door should be closed
  229.       ;
  230.  
  231.       On error (carry set), AX will hold an error code: 0001H (invalid
  232.       function), 0005H (access denied), 0006H (invalid handle), or
  233.       000DH (invalid data).
  234.  
  235.       The drive should be reset after closing the door before
  236.       accessing the drive (see question 3.05, How do I reset the
  237.       drive?).
  238. ----------------------------------------------------------------------
  239. 3.03. How do I unlock the door?
  240.  
  241.       First, you need the name of the device driver (see question 2.03,
  242.       How do I get the name of the CD-ROM device driver?). Open the
  243.       file for read/write and obtain the file handle (DOS function 3DH
  244.       will suffice).
  245.  
  246.       Once you have the file handle, you need a two-byte block of
  247.       memory. Call DOS IOCTL function 4403H, as shown here:
  248.  
  249.       mov  BX,FileHandle
  250.       mov  Command,1
  251.       mov  Command+1,0
  252.       lds  DX,Command
  253.       mov  CX,2
  254.       mov  AX,4403H
  255.       int  21H
  256.       jc   error
  257.       cmp  AX,2
  258.       jne  write_error
  259.       ;
  260.       ; door should be unlocked
  261.       ;
  262.  
  263.       On error (carry set), AX will hold an error code: 0001H (invalid
  264.       function), 0005H (access denied), 0006H (invalid handle), or
  265.       000DH (invalid data).
  266.  
  267.       The drive should be reset after unlocking the door before
  268.       accessing the drive (see question 3.05, How do I reset the
  269.       drive?).
  270. ----------------------------------------------------------------------
  271. 3.04. How do I lock the door?
  272.  
  273.       First, you need the name of the device driver (see question 2.03,
  274.       How do I get the name of the CD-ROM device driver?). Open the
  275.       file for read/write and obtain the file handle (DOS function 3DH
  276.       will suffice).
  277.  
  278.       Once you have the file handle, you need a two-byte block of
  279.       memory. Call DOS IOCTL function 4403H, as shown here:
  280.  
  281.       mov  BX,FileHandle
  282.       mov  Command,1
  283.       mov  Command+1,1
  284.       lds  DX,Command
  285.       mov  CX,2
  286.       mov  AX,4403H
  287.       int  21H
  288.       jc   error
  289.       cmp  AX,2
  290.       jne  write_error
  291.       ;
  292.       ; door should be locked
  293.       ;
  294.  
  295.       On error (carry set), AX will hold an error code: 0001H (invalid
  296.       function), 0005H (access denied), 0006H (invalid handle), or
  297.       000DH (invalid data).
  298.  
  299.       The drive should be reset after locking the door before
  300.       accessing the drive (see question 3.05, How do I reset the
  301.       drive?).
  302. ----------------------------------------------------------------------
  303. 3.05. How do I reset the drive?
  304.  
  305.       First, you need the name of the device driver (see question 2.03,
  306.       How do I get the name of the CD-ROM device driver?). Open the
  307.       file for read/write and obtain the file handle (DOS function 3DH
  308.       will suffice).
  309.  
  310.       Once you have the file handle, you need a one-byte block of
  311.       memory. Call DOS IOCTL function 4403H, as shown here:
  312.  
  313.       mov  BX,FileHandle
  314.       mov  Command,2
  315.       lds  DX,Command
  316.       mov  CX,1
  317.       mov  AX,4403H
  318.       int  21H
  319.       jc   error
  320.       cmp  AX,1
  321.       jne  write_error
  322.       ;
  323.       ; drive should be reset
  324.       ;
  325.  
  326.       On error (carry set), AX will hold an error code: 0001H (invalid
  327.       function), 0005H (access denied), 0006H (invalid handle), or
  328.       000DH (invalid data).
  329. ----------------------------------------------------------------------
  330. 3.06. How do I get drive status?
  331.  
  332.       First, you need the name of the device driver (see question 2.03,
  333.       How do I get the name of the CD-ROM device driver?). Open the
  334.       file for read/write and obtain the file handle (DOS function 3DH
  335.       will suffice).
  336.  
  337.       Once you have the file handle, you need a five-byte block of
  338.       memory. Call DOS IOCTL function 4402H, as shown here:
  339.  
  340.       mov  BX,FileHandle
  341.       mov  Command,6
  342.       lds  DX,Command
  343.       mov  CX,5
  344.       mov  AX,4402H
  345.       int  21H
  346.       jc   error
  347.       cmp  AX,5
  348.       jne  read_error
  349.       ;
  350.       ; The word at offset 1 of the five-byte block of memory contains
  351.       ; status
  352.       ; bit 10 is set if audio is playing
  353.       ; bit  9 is set if Red Book and HSG addressing are both
  354.       ;                  supported
  355.       ; bit  8 is set if audio channel control is supported
  356.       ; bit  7 is set if prefetch requests are supported
  357.       ; bit  5 is set if interleaving is supported
  358.       ; bit  4 is set if audio/video track playback is supported
  359.       ; bit  3 is set if the CD-ROM is writable
  360.       ; bit  2 is set if raw and cooked read is supported
  361.       ; bit  1 is set if the door is unlocked
  362.       ; bit  0 is set if the door is open
  363.       ;
  364.  
  365.       On error (carry set), AX will hold an error code: 0001H (invalid
  366.       function), 0005H (access denied), 0006H (invalid handle), or
  367.       000DH (invalid data).
  368.  
  369.       The drive should be reset after checking drive status before
  370.       accessing the drive (see question 3.05, How do I reset the
  371.       drive?).
  372. ======================================================================
  373. Section 4 - Drive Capacity
  374. ======================================================================
  375. 4.01. What sector size is supported?
  376.  
  377.       First, you need the name of the device driver (see question 2.03,
  378.       How do I get the name of the CD-ROM device driver?). Open the
  379.       file for read/write and obtain the file handle (DOS function 3DH
  380.       will suffice).
  381.  
  382.       Once you have the file handle, you need a four-byte block of
  383.       memory. Call DOS IOCTL function 4402H, as shown here:
  384.  
  385.       mov  BX,FileHandle
  386.       mov  Command,7
  387.       lds  DX,Command
  388.       mov  CX,4
  389.       mov  AX,4402H
  390.       int  21H
  391.       jc   error
  392.       cmp  AX,4
  393.       jne  read_error
  394.       ;
  395.       ; The byte at offset 1 of the four-byte block of memory contains
  396.       ; raw/cooked status (0 = cooked, 1 = raw)
  397.       ; The word at offset 2 of the four-byte block of memory contains
  398.       ; the sector size
  399.  
  400.       On error (carry set), AX will hold an error code: 0001H (invalid
  401.       function), 0005H (access denied), 0006H (invalid handle), or
  402.       000DH (invalid data).
  403.  
  404.       The drive should be reset after getting the sector size before
  405.       accessing the drive (see question 3.05, How do I reset the
  406.       drive?).
  407. ----------------------------------------------------------------------
  408. 4.02. How many sectors are on the disk?
  409.  
  410.       First, you need the name of the device driver (see question 2.03,
  411.       How do I get the name of the CD-ROM device driver?). Open the
  412.       file for read/write and obtain the file handle (DOS function 3DH
  413.       will suffice).
  414.  
  415.       Once you have the file handle, you need a five-byte block of
  416.       memory. Call DOS IOCTL function 4402H, as shown here:
  417.  
  418.       mov  BX,FileHandle
  419.       mov  Command,8
  420.       lds  DX,Command
  421.       mov  CX,5
  422.       mov  AX,4402H
  423.       int  21H
  424.       jc   error
  425.       cmp  AX,5
  426.       jne  read_error
  427.       ;
  428.       ; The dword at offset 1 of the five-byte block of memory
  429.       ; contains the number of sectors
  430.  
  431.       On error (carry set), AX will hold an error code: 0001H (invalid
  432.       function), 0005H (access denied), 0006H (invalid handle), or
  433.       000DH (invalid data).
  434.  
  435.       The drive should be reset after getting the number of sectors
  436.       before accessing the drive (see question 3.05, How do I reset
  437.       the drive?).
  438. ----------------------------------------------------------------------
  439. 4.03. How much data is on the disk?
  440.  
  441.       See question 4.01, What sector size is supported?, and question
  442.       4.02, How many sectors are on the disk?. Take the product of the
  443.       two values returned. The conventional DOS functions don't work
  444.       reliably.
  445. ======================================================================
  446. Section 5 - Volume Table of Contents
  447. ======================================================================
  448. 5.01. How do I get the abstract file name?
  449.  
  450.       You need a 38-byte block of memory to hold the abstract file
  451.       name. This code will fill that block:
  452.  
  453.       les  BX,Buffer
  454.       mov  CX,Drive    ; must be in format 0 = A:, 1 = B:, etc.
  455.       mov  AX,1503H
  456.       int  2FH
  457.       jc   error
  458.       ;
  459.       ; buffer is filled with the abstract file name.
  460.       ;
  461.  
  462.       The file name is nul-terminated.
  463.  
  464.       The drive should be reset after getting the abstract file name
  465.       before accessing the drive (see question 3.05, How do I reset
  466.       the drive?).
  467. ----------------------------------------------------------------------
  468. 5.02. How do I get the bibliography file name?
  469.  
  470.       You need a 38-byte block of memory to hold the bibliography file
  471.       name. This code will fill that block:
  472.  
  473.       les  BX,Buffer
  474.       mov  CX,Drive    ; must be in format 0 = A:, 1 = B:, etc.
  475.       mov  AX,1504H
  476.       int  2FH
  477.       jc   error
  478.       ;
  479.       ; buffer is filled with the bibliography file name.
  480.       ;
  481.  
  482.       The file name is nul-terminated.
  483.  
  484.       The drive should be reset after getting the bibliography file
  485.       name before accessing the drive (see question 3.05, How do I
  486.       reset the drive?).
  487. ----------------------------------------------------------------------
  488. 5.03. How do I get the copyright file name?
  489.  
  490.       You need a 38-byte block of memory to hold the copyright file
  491.       name. This code will fill that block:
  492.  
  493.       les  BX,Buffer
  494.       mov  CX,Drive    ; must be in format 0 = A:, 1 = B:, etc.
  495.       mov  AX,1502H
  496.       int  2FH
  497.       jc   error
  498.       ;
  499.       ; buffer is filled with the copyright file name.
  500.       ;
  501.  
  502.       The file name is nul-terminated.
  503.  
  504.       The drive should be reset after getting the copyright file name
  505.       before accessing the drive (see question 3.05, How do I reset
  506.       the drive?).
  507. ----------------------------------------------------------------------
  508. 5.04. How do I read the Volume Table of Contents (VTOC)?
  509.  
  510.       The VTOC is read in 2048-byte blocks. This code fills a VTOC
  511.       block:
  512.  
  513.       les  BX,Buffer
  514.       mov  CX,Drive       ; must be in format 0 = A:, 1 = B:, etc.
  515.       mov  DX,BlockNumber ; 0 for the first block
  516.       mov  AX,1505H
  517.       int  2FH
  518.       jc   error
  519.       ;
  520.       ; block is filled
  521.       ;
  522.       ; AX contains the descriptor type for this block:
  523.       ;  0001H = standard volume descriptor
  524.       ;  00FFH = volume descriptor terminator
  525.       ;
  526.  
  527.       On error, AX will hold an error value: 000FH (invalid drive) or
  528.       0015H (drive not ready).
  529. ======================================================================
  530. Section 6 - Audio
  531. ======================================================================
  532. 6.01. How do I find out how many tracks are on a CD?
  533.  
  534.       First, you need the name of the device driver (see question
  535.       2.03, How do I get the name of the CD-ROM device driver?). Open
  536.       the file for read/write and obtain the file handle (DOS function
  537.       3DH will suffice).
  538.  
  539.       Once you have the file handle, you need a seven-byte block of
  540.       memory. Call DOS IOCTL function 4402H, as shown here:
  541.  
  542.       mov  BX,FileHandle
  543.       mov  Command,0AH
  544.       lds  DX,Command
  545.       mov  CX,7
  546.       mov  AX,4402H
  547.       int  21H
  548.       jc   error
  549.       cmp  AX,7
  550.       jne  read_error
  551.       ;
  552.       ; The byte at offset 1 of the seven-byte block of memory is the
  553.       ; number of the first track
  554.       ; The byte at offset 2 of the seven-byte block of memory is the
  555.       ; number of the last track
  556.       ; The dword at offset 4 of the seven-byte block of memory is the
  557.       ; start address of the first track in Red Book format
  558.  
  559.       On error (carry set), AX will hold an error code: 0001H (invalid
  560.       function), 0005H (access denied), 0006H (invalid handle), or
  561.       000DH (invalid data).
  562. ----------------------------------------------------------------------
  563. 6.02. What are Red Book and HSG formats?
  564.  
  565.       Both are ways of encoding frame information. An audio frame is
  566.       1/75 second of audio. HSG encodes frame information into a
  567.       double word: minute multiplied by 4500, plus second multiplied
  568.       by 75, plus frame, minus 150. Red Book encodes frame information
  569.       into a four-byte data structure:
  570.        Byte 0: frame number
  571.        Byte 1: second
  572.        Byte 2: minute
  573.        Byte 3: unused
  574. ----------------------------------------------------------------------
  575. 6.03. How can I determine where a particular track starts?
  576.  
  577.       First, you need the name of the device driver (see question
  578.       2.03, How do I get the name of the CD-ROM device driver?). Open
  579.       the file for read/write and obtain the file handle (DOS function
  580.       3DH will suffice).
  581.  
  582.       Once you have the file handle, you need an eight-byte block of
  583.       memory. Call DOS IOCTL function 4402H, as shown here:
  584.  
  585.       mov  BX,FileHandle
  586.       mov  Command,0BH
  587.       mov  Command+1,TrackNumber
  588.       lds  DX,Command
  589.       mov  CX,8
  590.       mov  AX,4402H
  591.       int  21H
  592.       jc   error
  593.       cmp  AX,8
  594.       jne  read_error
  595.       ;
  596.       ; The dword at offset 2 of the eight-byte block of memory is the
  597.       ; start address of the specified track in Red Book format
  598.       ; The word at offset 6 of the eight-byte block of memory is the
  599.       ; track control information. Bits 15-12 are used:
  600.       ; 0xxx: Two audio channels, no pre-emphasis, digital copy not
  601.       ;       permitted
  602.       ; 1xxx: Two audio channels, with pre-emphasis, digital copy not
  603.       ;       permitted
  604.       ; 2xxx: Two audio channels, no pre-emphasis, digital copy
  605.       ;       permitted
  606.       ; 3xxx: Two audio channels, with pre-emphasis, digital copy
  607.       ;       permitted
  608.       ; 4xxx: Data track, digital copy not permitted
  609.       ; 6xxx: Data track, digital copy permitted
  610.       ; 8xxx: Four audio channels, no pre-emphasis, digital copy not
  611.       ;       permitted
  612.       ; 9xxx: Four audio channels, with pre-emphasis, digital copy not
  613.       ;       permitted
  614.       ; Axxx: Four audio channels, no pre-emphasis, digital copy
  615.       ;       permitted
  616.       ; Bxxx: Four audio channels, with pre-emphasis, digital copy
  617.       ;       permitted
  618.  
  619.       On error (carry set), AX will hold an error code: 0001H (invalid
  620.       function), 0005H (access denied), 0006H (invalid handle), or
  621.       000DH (invalid data).
  622. ----------------------------------------------------------------------
  623. 6.04. How do I play audio?
  624.  
  625.       For starters, you need MSCDEX Version 2.1 or greater (see
  626.       question 1.02, How do I determine the MSCDEX version?).
  627.  
  628.       You also need the subunit number for the drive containing the
  629.       audio CD (see question 2.03, How do I get the name of the CD-ROM
  630.       device driver?)
  631.  
  632.       You also need to know what frame you want to start with (see
  633.       question 6.03, How can I determine where a particular track
  634.       starts?), and how many frames you want to play.
  635.  
  636.       Now, you need a 22-byte block of memory. Write 22 (16H) to the
  637.       first byte. Write the subunit number to the second byte. Write
  638.       84H to the third byte. Write 0 to the byte at offset 0DH (this
  639.       sets up HSG addressing). Convert the starting frame number to
  640.       HSG format and write the 4-byte result to the dword at offset
  641.       0EH. Finally, write the frame count to the dword at offset 12H.
  642.  
  643.       To play the CD as instructed, execute this code:
  644.  
  645.       les  BX,Buffer
  646.       mov  CX,Drive    ; must be in format 0 = A:, 1 = B:, etc.
  647.       mov  AX,1510H
  648.       int  2FH
  649.       ;
  650.       ; status is in the word at offset 3 of the buffer. Look for bit
  651.       ; 8 set (done), and watch out for bit 15 set (error).
  652.       ;
  653. ----------------------------------------------------------------------
  654. 6.05. How do I pause audio playback?
  655.  
  656.       For starters, you need MSCDEX Version 2.1 or greater (see
  657.       question 1.02, How do I determine the MSCDEX version?).
  658.  
  659.       You also need the subunit number for the drive containing the
  660.       audio CD (see question 2.03, How do I get the name of the CD-ROM
  661.       device driver?)
  662.  
  663.       Now, you need a 13-byte block of memory. Write 13 (0DH) to the
  664.       first byte. Write the subunit number to the second byte. Write
  665.       85H to the third byte.
  666.  
  667.       To pause the CD, execute this code:
  668.  
  669.       les  BX,Buffer
  670.       mov  CX,Drive    ; must be in format 0 = A:, 1 = B:, etc.
  671.       mov  AX,1510H
  672.       int  2FH
  673.       ;
  674.       ; status is in the word at offset 3 of the buffer. Look for bit
  675.       ; 8 set (done), and watch out for bit 15 set (error).
  676.       ;
  677. ----------------------------------------------------------------------
  678. 6.06. How do I resume audio playback?
  679.  
  680.       For starters, you need MSCDEX Version 2.1 or greater (see
  681.       question 1.02, How do I determine the MSCDEX version?).
  682.  
  683.       You also need the subunit number for the drive containing the
  684.       audio CD (see question 2.03, How do I get the name of the CD-ROM
  685.       device driver?)
  686.  
  687.       Now, you need a 13-byte block of memory. Write 13 (0DH) to the
  688.       first byte. Write the subunit number to the second byte. Write
  689.       88H to the third byte.
  690.  
  691.       To resume, execute this code:
  692.  
  693.       les  BX,Buffer
  694.       mov  CX,Drive    ; must be in format 0 = A:, 1 = B:, etc.
  695.       mov  AX,1510H
  696.       int  2FH
  697.       ;
  698.       ; status is in the word at offset 3 of the buffer. Look for bit
  699.       ; 8 set (done), and watch out for bit 15 set (error).
  700.       ;
  701.  
  702.  
  703.  
  704.